import { Sprite_Base } from "@/sprites/Sprite_Base.js";

export class Sprite_Battler extends Sprite_Base {
    constructor() {
        super();
        this.anchor.set(0.5,1);

        this._battler = null;
        this._damages = [];
        this._homeX = 0;
        this._homeY = 0;
        this._offsetX = 0;
        this._offsetY = 0;
        this._targetOffsetX = 0;
        this._targetOffsetY = 0;
        this._movementDuration = 0;
        this._selectionEffectCount = 0;
        this._selectionEffectEnabled = false;
    }

    setBattler(battler) {
        if(this._battler!=battler){
            this.deattachHandler();
            this._battler = battler;
            if (!this._battler || !this._battler.isSpriteVisible()) {
                this.visible = false;
            } else {
                this.attachHandler();
                this.visible = true;
            }
        }
    }

    attachHandler() {
        if (this._battler) {
            this._attachHandler(this._battler);
        }
    }
    deattachHandler(){
        if (this._battler?.isSpriteVisible()) {
            this._deattachHandler(this._battler);
        }
    }
    _attachHandler(battler){
        battler.on('animation', (data) => {
            let animation = $dataAnimations[data.animationId];
            let mirror = data.mirror;
            let delay = animation.position === 3 ? 0 : data.delay;
            this.startAnimation(animation, mirror, delay);
        }).on('damage-popup', () => {
            let sprite = new Sprite_Damage();
            sprite.x = this.x + this.damageOffsetX();
            sprite.y = this.y + this.damageOffsetY();
            sprite.setup(this._battler);
            this._damages.push(sprite);
            this.parent.addChild(sprite);
        }).on('selected', this.onSelected)
        .on('deselected', this.onDeSelected);
    }

    _deattachHandler(battler){
        battler.off('animation')
        .off('damage-popup')
        .off('selected')
        .off('deselected');
    }

    destroy(opts){
        this.deattachHandler();
        super.destroy(opts);
    }

    onSelected=()=>{
        this._selectionEffectEnabled = true;
    }
    onDeSelected=()=>{
        this._selectionEffectEnabled = false;
        this._effectTarget.setBlendColor([0, 0, 0, 0]);
    }

    setHome(x, y) {
        this._homeX = x;
        this._homeY = y;
        this.updatePosition();
    }

    update() {
        super.update();
        if (this._battler) {
            this.updateMain();
            this.updateDamagePopup();
            this.updateSelectionEffect();
        }
    }

    updateMain() {
        if (this._battler.isSpriteVisible()) {
            this.updateSource();
            this.updateFrame();
        }
        this.updateMove();
    }

    updateSource() { }
    updateFrame() { }

    updateMove() {
        if (this._movementDuration > 0) {
            let d = this._movementDuration;
            this._offsetX = (this._offsetX * (d - 1) + this._targetOffsetX) / d;
            this._offsetY = (this._offsetY * (d - 1) + this._targetOffsetY) / d;
            --this._movementDuration;
            if (this._movementDuration == 0) {
                this.onMoveEnd();
            }
            this.updatePosition();
        }
    }

    updatePosition() {
        this.x = this._homeX + this._offsetX;
        this.y = this._homeY + this._offsetY;
    }

    updateDamagePopup() {
        if (this._damages.length > 0) {
            for (let i = 0; i < this._damages.length; i++) {
                this._damages[i].update();
            }
            if (!this._damages[0].isPlaying()) {
                this.parent.removeChild(this._damages[0]);
                this._damages.shift();
            }
        }
    }

    updateSelectionEffect() {
        if (this._selectionEffectEnabled && this._effectTarget) {
            this._selectionEffectCount++;
            if (this._selectionEffectCount % 30 < 15) {
                this._effectTarget.setBlendColor([255, 255, 255, 64]);
            } else {
                this._effectTarget.setBlendColor([0, 0, 0, 0]);
            }
        }
    }

    damageOffsetX() { return 0; }
    damageOffsetY() { return 0; }

    startMove(x, y, duration) {
        if (this._targetOffsetX != x || this._targetOffsetY != y) {
            this._targetOffsetX = x;
            this._targetOffsetY = y;
            this._movementDuration = duration;
            if (duration == 0) {
                this._offsetX = x;
                this._offsetY = y;
                this.updatePosition();
            }
        }
    }

    onMoveEnd() { }
    isEffecting() { return this._selectionEffectEnabled; }
    isMoving() { return this._movementDuration > 0; }
    inHomePosition() { return this._offsetX == 0 && this._offsetY == 0; }
    isBusy(){
        return this.isAnimationPlaying()||
        this._damages.length>0||
        this.isMoving();
    }
}